<?php

use console\db\Migration;
use yii\db\Query;

/**
 * 用户签到周期历史
 * 
 * @author emhome <emhome@163.com>
 * @since 1.0
 */
class m300030_000040_t_signin_history extends Migration {

    /**
     * @inheritdoc
     */
    public $tableName = '{{%user_signin_log}}';

    /**
     * @inheritdoc
     */
    public function safeUp() {
        $this->truncateTable('{{%user_signin_history}}');
        $query = (new Query())->from($this->tableName)->select('user_id,count(*) as cnt')
        ->groupBy('user_id')
        ->having('count(*)>1');
        $this->handleProgress($query, [$this, 'evenDule']);
    }

    /**
     * @inheritdoc
     */
    public function safeDown() {
        $this->truncateTable('{{%user_signin_history}}');
    }

    /**
     * 处理结果
     * @param Migration $migration
     * @param array $rows
     */
    public static function evenDule($migration, $rows) {
        if (empty($rows)) {
            return;
        }
        $query = (new Query())->from($migration->tableName)->orderBy('created_at asc');
        $data = [];
        $connect = $migration->db->createCommand();
        $columns = [
            'user_id',
            'days',
            'first_date',
            'created_at',
            'updated_at',
            'last_date',
            'sign_days',
            'history',
        ];
        foreach ($rows as $row) {
            $signins = static::formatQuery($query, $row['user_id']);
            if (empty($signins)) {
                continue;
            }
            if ($row['cnt'] > 200) {
                $connect->batchInsert('{{%user_signin_history}}', $columns, $signins)->execute();
                continue;
            }
            $data = array_merge($data, $signins);
        }
        $connect->batchInsert('{{%user_signin_history}}', $columns, $data)->execute();
    }

    /**
     * 签到格式化
     * @param \yii\db\Query $query Description
     * @return array
     */
    public static function formatQuery(Query $query, $uid, $db = null) {
        $query->where(['user_id' => $uid]);
        $months = [];
        $monthDays = [];
        foreach ($query->each(100, $db) as $log) {
            $key = date('Ym', $log['created_at']);
            $date = date('Y-m-d', $log['created_at']);
            $index = date('j', $log['created_at']) - 1;
            if (!isset($months[$key])) {
                $days = date('t', $log['created_at']);
                for ($i = 0; $i < $days; $i++) {
                    $months[$key][$i] = 0;
                }
                $monthDays[$key] = [
                    'user_id' => $uid,
                    'days' => $days,
                    'first_date' => $date,
                    'created_at' => $log['created_at'],
                ];
            }
            $months[$key][$index] = 1;
            $monthDays[$key]['updated_at'] = $log['created_at'];
            $monthDays[$key]['last_date'] = $date;
        }
        foreach ($months as $month => $days) {
            while (!array_pop($days)) {
                continue;
            }
            $bindays = implode('', $days) . '1';
            $monthDays[$month]['sign_days'] = substr_count($bindays, '1');
            $monthDays[$month]['history'] = bindec($bindays);
        }
        return $monthDays;
    }

    /**
     * 签到格式化
     * @return array
     */
    public static function format($data) {
        $months = [];
        $monthDays = [];
        foreach ($data as $log) {
            $key = date('Ym', $log['inputtime']);
            $date = date('Y-m-d', $log['inputtime']);
            $index = date('j', $log['inputtime']) - 1;
            if (!isset($months[$key])) {
                $days = date('t', $log['inputtime']);
                for ($i = 0; $i < $days; $i++) {
                    $months[$key][$i] = 0;
                }
                $monthDays[$key] = [
                    'user_id' => $log['uid'],
                    'days' => $days,
                    'first_date' => $date,
                    'created_at' => $log['inputtime'],
                ];
            }
            $months[$key][$index] = 1;
            $monthDays[$key]['updated_at'] = $log['inputtime'];
            $monthDays[$key]['last_date'] = $date;
        }
        foreach ($months as $month => $days) {
            while (!array_pop($days)) {
                continue;
            }
            $days[] = 1;
            $monthDays[$month]['history'] = bindec(implode('', $days));
        }
        return $monthDays;
    }

}
